package org.example.myframework.frame.demo.websocket;

import lombok.extern.slf4j.Slf4j;
import org.example.myframework.frame.common.websocket.config.WebSocketServerConfig;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@Slf4j
@ServerEndpoint(value = "/ws/erp", configurator = WebSocketServerConfig.class)
public class ErpWebsocket {

    /**
     * 记录当前在线的连接数
     */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * 存放所有的在线客户端
     */
    private static Map<String, ErpWebsocket> clients = new ConcurrentHashMap<>();

    /**
     * 某个客户端连接的session会话
     */
    private Session session;

    // 标识当前会话的key
    private String erp = "";

    /**
     * 进行连接之后需要执行的方法
     * @param session
     * @param config
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException {
        Map<String, Object> userProperties = config.getUserProperties();
        String erp = (String) userProperties.get("erp");
        this.erp = erp;
        this.session = session;
        if (clients.containsKey(this.erp)) {
            // 关闭掉老的会话
            clients.get(this.erp).session.close();
            clients.remove(this.erp);
            // 在线数目 -1
            onlineCount.decrementAndGet();
        }
        // 将新的会话塞入
        clients.put(this.erp, this);
        onlineCount.incrementAndGet();
        log.info("有新连接加入{}，当前在线人数:{}", erp, onlineCount.get());
        sendMessage("连接成功", session);
    }

    public void sendMessage(String message, Session session) throws IOException {
        log.info("服务端给客户端发送消息：{}，内容为{}", this.erp, message);
        session.getBasicRemote().sendText(message);
    }

    /**
     * 关闭连接
     * @throws IOException
     */
    @OnClose
    public void close() throws IOException {
        if (clients.containsKey(this.erp)) {
            clients.get(this.erp).session.close();
            clients.remove(this.erp);
        }
        onlineCount.decrementAndGet();
    }

    @OnMessage
    public void onMessage(String messsage, Session session) throws IOException {
        log.info("服务端收到客户端{}消息：{}", this.erp, messsage);
        // 心跳机制，防止ws超时断联
        if (messsage.equals("ping")) {
            this.sendMessage("pong", session);
        }
    }
}
